﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace DotSpatial.Controls
{
    /// <summary>
    /// 继承自缩放控件，中轴拖动地图，新增：增删改点逻辑，按住左键拖动地图逻辑，双击自定义事件
    /// </summary>
    public class CustomMapFunction : DotSpatial.Controls.MapFunctionZoom
    {
        #region Public Delegate
        public delegate void CustomMethodDelegate(GeoMouseArgs e);
        #endregion

        #region Public Variables
        public CustomMethodDelegate OnCustomMousMove;
        public CustomMethodDelegate OnInsertingMousUp;
        public CustomMethodDelegate OnDraggingMousMove;
        public CustomMethodDelegate OnDraggingMousUp;
        public CustomMethodDelegate OnDeletingMouseUp;
        public CustomMethodDelegate OnCustomDoubleClick;
        #endregion

        #region Private Variables   
        private bool _isDragging;
        private bool _preventDrag;
        private Rectangle _source;
        private Point _dragStart;

        public bool _enableDrag;//是否允许拖动地物
        public bool _enableInsert;//是否允许新增地物
        public bool _enableDelete;//是否允许删除地物
        public bool _mousdown { get; private set; }//鼠标已经按下

        #endregion

        #region Constructors

        /// <summary>
        /// Initializes a new instance of the MapFunctionZoom class.
        /// </summary>
        public CustomMapFunction(IMap inMap)
            : base(inMap)
        {
        }

        #endregion

        #region Protected Methods

        /// <summary>
        /// 鼠标按下事件
        /// 增删改都不可用时才触发拖动事件
        /// </summary>
        /// <param name="e"></param>
        protected override void OnMouseDown(GeoMouseArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                _mousdown = true;//标记鼠标按下 
                if (!_preventDrag && !_enableDrag && !_enableDelete && !_enableInsert)
                {
                    _dragStart = e.Location;
                    _source = e.Map.MapFrame.View;
                }
            }
            base.OnMouseDown(e);
        }

        /// <summary>
        /// 鼠标双击事件
        /// 当增删改都不可用时才触发
        /// </summary>
        /// <param name="e"></param>
        protected override void OnMouseDoubleClick(GeoMouseArgs e)
        {
            if (e.Button == MouseButtons.Left && !_enableDelete && !_enableDrag && !_enableInsert)
            {
                if (this.OnCustomDoubleClick != null)
                {
                    this.OnCustomDoubleClick(e);
                }
            }
            base.OnMouseDoubleClick(e);
        }
        /// <summary>
        /// 鼠标移动事件
        /// 当拖动地图时，不触发增删改事件
        /// </summary>
        /// <param name="e"></param>
        protected override void OnMouseMove(GeoMouseArgs e)
        {
            _isDragging = true;
            if (_dragStart != Point.Empty && !_preventDrag)
            {
                if (!BusySet)
                {
                    Map.IsBusy = true;
                    BusySet = true;
                }

                Point diff = new Point { X = _dragStart.X - e.X, Y = _dragStart.Y - e.Y };
                e.Map.MapFrame.View = new Rectangle(_source.X + diff.X, _source.Y + diff.Y, _source.Width, _source.Height);
                Map.Invalidate();
            }
            else
            {
                if (OnCustomMousMove != null)
                {
                    OnCustomMousMove(e);
                }

                if (_enableDrag && _mousdown && _isDragging)
                {
                    if (OnDraggingMousMove != null)
                    {
                        OnDraggingMousMove(e);
                    }
                }
            }
            base.OnMouseMove(e);
        }

        /// <summary>
        /// 鼠标释放事件
        /// 当拖动鼠标抬起时，如果移动点不可用，执行地图拖动，否则执行移动点操作
        /// 如果新增可用，执行新增事件
        /// 如果删除可用，执行删除事件
        /// </summary>
        /// <param name="e"></param>
        protected override void OnMouseUp(GeoMouseArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                if (_isDragging)
                {
                    if (!_enableDrag)
                    {
                        _preventDrag = true;
                        e.Map.MapFrame.ResetExtents();
                        _preventDrag = false;
                        Map.IsBusy = false;
                        BusySet = false;
                    }
                    if (_enableDrag && _mousdown)
                    {
                        //  this.DisenableMethod();
                        if (OnDraggingMousUp != null)
                        {
                            OnDraggingMousUp(e);
                        }
                    }
                    _isDragging = false;
                }
                _mousdown = false;
                _dragStart = Point.Empty;

                if (_enableInsert)
                {
                    if (OnInsertingMousUp != null)
                    {
                        OnInsertingMousUp(e);
                    }
                }
                if (_enableDelete)
                {
                    if (OnDeletingMouseUp != null)
                    {
                        OnDeletingMouseUp(e);
                    }
                }

            }

            base.OnMouseUp(e);
        }

        #endregion

        #region Public Methods
        /// <summary>
        /// 激活某事件，单选
        /// </summary>
        /// <param name="method"></param>
        public void EnableMethod(MethodEnum method)
        {
            switch (method)
            {
                case MethodEnum.Drag:
                    this.DisenableMethod();
                    this._enableDrag = true;
                    break;
                case MethodEnum.Insert:
                    this.DisenableMethod();
                    this._enableInsert = true;
                    break;
                case MethodEnum.Delete:
                    this.DisenableMethod();
                    this._enableDelete = true;
                    break;
                default:
                    break;
            }
        }

        /// <summary>
        /// 禁用增删改事件
        /// </summary>
        public void DisenableMethod()
        {
            _enableDelete = false;
            _enableDrag = false;
            _enableInsert = false;
        }
        #endregion
    }

    public enum MethodEnum
    {
        Drag = 1,
        Insert = 2,
        Delete = 3
    }
}
